package app.controller;

import app.entity.ScanRecord;
import app.entity.UserSession;
import app.utils.*;
import app.wechat.pojo.WeChat;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
//import com.swetake.util.Qrcode;
import common.standard.table.ModelAttributeEnum;
import common.standard.view.ViewNameEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import refactor.entity.User;
import refactor.service.IUserService;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 这个类用于PC用户的登录
 * @author 昊琦
 * 创建时间：2018-3-2 15:51:12
 */
@Slf4j
@Controller
public class Login {

    @Resource(name="wechat")
    private WeChat wechat;

    private IUserService userService;

    @Autowired
    public void setUserService(IUserService userService) {
        this.userService = userService;
    }

    private String machineKey(){
        UUID randomUUID = UUID.randomUUID();
        return new Md5().getDigest(randomUUID.toString()+System.currentTimeMillis());
    }

    /**
     * 处理用户登录的get和post请求
     *
     * @param name 用户名
     * @param password 用户密码
     * @param verificationcode 验证码
     * @param operate 操作
     * @param returnurl 返回的url
     * @param request http请求
     * @param session session
     * @param model 模型
     * @return 跳转到登录页面
     */
    @RequestMapping(value="/login")
    public String loginPost(@RequestParam(value="name",defaultValue="")String name,
                            @RequestParam(value="password",defaultValue="")String password,
                            @RequestParam(value="verificationcode",defaultValue="")String verificationcode,
                            @RequestParam(value="operate",defaultValue="")String operate,
                            @RequestParam(value="returnurl",defaultValue="")String returnurl,
                            HttpServletRequest request, HttpSession session, Model model ){

//        if(name.equals("test")){
//            return "wechat/binddevice";
//        }


        log.info("app.controller.Login loginPost() 开始执行"+machineKey());
        model.addAttribute(ModelAttributeEnum.MIC.getAttributeName(), machineKey());
        model.addAttribute(ModelAttributeEnum.PAGE_TITLE.getAttributeName(), "登录页面");
        model.addAttribute(ModelAttributeEnum.SUB_TITLE.getAttributeName(), "首页");
        model.addAttribute(ModelAttributeEnum.APP_NAME.getAttributeName(), Common.appName);
        model.addAttribute(ModelAttributeEnum.COMPANY_NAME.getAttributeName(), Common.companyName);
        model.addAttribute(ModelAttributeEnum.WE_CHAT.getAttributeName(), wechat);
        model.addAttribute(ModelAttributeEnum.RETURN_URL.getAttributeName(), returnurl);

        String basePath = BasePathCollector.getBasePathWithoutPort(request);
        model.addAttribute(ModelAttributeEnum.BASE_PATH.getAttributeName(), basePath);

        // 二维码图片需要使用的登录机器码
        String mcid = "";
        model.addAttribute(ModelAttributeEnum.MCID.getAttributeName(), mcid);

        // 接收到表单登录数据的时候的查询到的用户存放在这里
        User item = null;

        // 如果操作参数为空或者空字符串
        if(StringUtils.isBlank(operate)){

            if (wechat.getEnable()) {

                // 获取ip
                String ip = Common.getRemoteIP(request, null);

                // 计算登录页面需要用到的机器码
                mcid = new Md5().getDigest(new SimpleDateFormat("MMddHHmmssSSS").format(new Date()) + ip + StringUtil.getRandomString(4));
                log.info("Login loginPost()方法，成功生成微信登录机器码"+machineKey());

                // 在model中放入mcid
                log.info(mcid);
                model.addAttribute(ModelAttributeEnum.MCID.getAttributeName(), mcid);
                log.info("Lo");
            }
            // 判断用户是否已经登录
            if (session.getAttribute(Common.sessionUser) != null) {

                UserSession user = (UserSession) session.getAttribute(Common.sessionUser);

                String jumpTo = BasePathCollector.getBasePathWithoutPort(request) + user.getRoleId() + "/index";
                //放入model中jumpto和message
                model.addAttribute(ModelAttributeEnum.JUMP_TO.getAttributeName(), jumpTo);
                model.addAttribute(ModelAttributeEnum.MESSAGE.getAttributeName(), "已经登录，无需重复登录！");

                return ViewNameEnum.JUMPER.getViewName();

            } else {

                // 到登录输入用户名密码的页面
                return ViewNameEnum.LOGIN.getViewName();
            }

        } else if ("loginform".equals(operate)) {
            //处理表单登录操作

            verificationcode = verificationcode.toUpperCase();

            if (StringUtils.isBlank(name) || StringUtils.isBlank(password)) {
                //放入model中jumpto和message
                model.addAttribute(ModelAttributeEnum.JUMP_TO.getAttributeName(), ViewNameEnum.LOGIN.getViewName());
                model.addAttribute(ModelAttributeEnum.MESSAGE.getAttributeName(), "请输入用户名和密码！");

                return ViewNameEnum.JUMPER.getViewName();
            } else {
                // 用md5摘要去检查

                item = userService.userLogin(name, password);

                String sessionVerificationCode = (String) session.getAttribute(Common.sessionVerificationCode);

                if (item == null || !sessionVerificationCode.equals(verificationcode)) {
                    // 记录日志
                    // 限制ip重试次数

                    String message = "用户名、密码或验证码不正确，请重新输入！";

                    //放入model中jumpto和message
                    model.addAttribute(ModelAttributeEnum.JUMP_TO.getAttributeName(), ViewNameEnum.LOGIN.getViewName());
                    model.addAttribute(ModelAttributeEnum.MESSAGE.getAttributeName(), message);

                    return ViewNameEnum.JUMPER.getViewName();
                } else if (!item.getFrozen().equals("0")) {
                    String message = "此用户已被冻结！";

                    //放入model中jumpto和message
                    model.addAttribute(ModelAttributeEnum.JUMP_TO.getAttributeName(), ViewNameEnum.LOGIN.getViewName());
                    model.addAttribute(ModelAttributeEnum.MESSAGE.getAttributeName(), message);

                    return ViewNameEnum.JUMPER.getViewName();
                } else if (item.getRoleId() == 3) {
                    String message = "施工/维护人员请在微信端登录";

                    //放入model中jumpto和message
                    model.addAttribute(ModelAttributeEnum.JUMP_TO.getAttributeName(), ViewNameEnum.LOGIN.getViewName());
                    model.addAttribute(ModelAttributeEnum.MESSAGE.getAttributeName(), message);

                    return ViewNameEnum.JUMPER.getViewName();
                } else {
                    log.info("pc端登录的用户为：" + item.getName());
                }
            }
        } else if ("wechatlogin".equals(operate)) {
            // 微信登录
            // 通过微信登录
            // 查询机器号码，获取微信openId，再读取用户信息
            String openId =null;
            ArrayList<ScanRecord> list = ScanRecordList.getList();
            for (ScanRecord scanRecord : list) {
                if (mcid.equals(scanRecord.getMcid())) {
                    openId = scanRecord.getOpenId();
                }
            }
            if (!StringUtils.isBlank(openId)) {
                QueryWrapper<User> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("open_id", openId);
                item = userService.getOne(queryWrapper);

                log.info("微信扫描登录的用户为：" + item.getName());
            }
        }

//        String oid="oY0y0wcRO09qXqwrXCqwPmc41U6s";
//        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//               queryWrapper.eq("open_id", oid);
//               item = userService.getOne(queryWrapper);
        // ------------------------------统一处理---------------------------
        UserSession userSession = new UserSession(item);
        session.setAttribute(Common.sessionUser, userSession);

        String jumpTo = StringUtils.isBlank(returnurl) ? basePath + item.getRoleId() + "/index" : returnurl;

        String message = "登录成功！";

        model.addAttribute(ModelAttributeEnum.JUMP_TO.getAttributeName(), jumpTo);
        model.addAttribute(ModelAttributeEnum.MESSAGE.getAttributeName(), message);

        log.info("app.controller.Login loginPost() 执行完成");
        return ViewNameEnum.JUMPER_ATONCE.getViewName();
    }

    /**
     * 返回在pc端使用微信扫描的二维码
     *
     * @param mcid 机器码
     * @param request http请求
     * @param response http响应
     */
    @RequestMapping(value="/getwechatqrcode")
    public void weChatLoginQRCode(@RequestParam(name="mcid",defaultValue="")String mcid, HttpServletRequest request, HttpServletResponse response){

//        //获取basePath
//        String basePath = BasePathCollector.getBasePathWithoutPort(request);
//
//        String loginUrl = basePath + "WLQRCode.do?mcid=" + mcid;
//        byte[] bytes;
//
//        BufferedImage image = getBufImg(loginUrl);
//        //将image 转成输入流
//        ByteArrayOutputStream bos = new ByteArrayOutputStream();
//
//        try {
//            javax.imageio.ImageIO.write(image, "jpg", bos);
//            bytes = bos.toByteArray();
//
//            InputStream inputStream = new ByteArrayInputStream(bytes);
//
//            DataResponse.StreamResponse(response, inputStream, "weChatLoginQRCode.jpg");
//
//        } catch (Exception ex) {
//            log.info(ex.getMessage());
//        } finally {
//            try {
//                bos.close();
//            } catch (Exception ex1) {
//                log.info(ex1.getMessage());
//            }
//        }

    }

    /**
     * 返回在电脑上登录时表单登录的验证码
     *
     * @param session session
     */
    @GetMapping("/verify")
    public ResponseEntity<byte[]> export(HttpSession session) throws NoSuchAlgorithmException, IOException {
        InputStream inputStream = new VerificationCode().doDefault(session);
        return DataResponse.fileResponse(inputStream, "verificationCode.jpg");
    }

    /**
     * 查询移动端扫描结果
     *
     * 查询到有扫描记录后，返回成功消息，由网页端跳转到登录页面
     * @param mcid
     * @param response
     */
    @RequestMapping(value="/acmsr")
    public void checkMcidScanRecord(String mcid,HttpServletResponse response){

        Map<String, String> map = new HashMap<>();
        // 查询移动端扫描结果
        String openId = "";
        ArrayList<ScanRecord> list = ScanRecordList.getList();
        if (!list.isEmpty()) {
            for (ScanRecord scanRecord : list) {
                if (mcid.equals(scanRecord.getMcid())) {
                    openId = scanRecord.getOpenId();
                    break;
                }
            }
            if (!openId.equals("")) {
                map.put("flag", "true"); // 标识位
                map.put("msg", "登陆成功，正在跳转..."); // 提示信息
                map.put("mcid", mcid);
                map.put("openId", openId);
            } else {
                map.put("flag", "false"); // 标识位
                map.put("msg", "请在微信端扫描"); // 提示信息
            }
        } else {
            map.put("flag", "false"); // 标识位
            map.put("msg", "请在微信端扫描"); // 提示信息
        }

        DataResponse.jsonResponse(response, map);

    }


    /**
     * 用户注销登录
     *
     * @param session session
     * @param model model
     * @return 返回到登录页面
     */
    @RequestMapping("/logout")
    public String logout(HttpSession session,Model model){

        //清空session里的用户数据
        session.removeAttribute(Common.sessionUser);
        session.removeAttribute(Common.sessionVerificationCode);
        session.invalidate();

        //跳转到登录页
        model.addAttribute(ModelAttributeEnum.JUMP_TO.getAttributeName(), ViewNameEnum.LOGIN.getViewName());
        model.addAttribute(ModelAttributeEnum.MESSAGE.getAttributeName(), "登录已注销...");

        return ViewNameEnum.JUMPER.getViewName();
    }


//    private BufferedImage getBufImg(String content) {
//
//        BufferedImage bufImg = null;
//
//        try {
//            // 7-124
//            // 8-154
//            // 9-182
//            // 10-216
//            int size = 6;// 二维码尺寸，取值范围1-40
//            Qrcode qrcode = new Qrcode();
//            qrcode.setQrcodeErrorCorrect('M');
//            // 设置二维码排错率，可选L(7%)、M(15%)、Q(25%)、H(30%)，排错率越高可存储的信息越少，但对二维码清晰度的要求越小
//            qrcode.setQrcodeEncodeMode('B');
//            // 设置设置二维码尺寸，取值范围1-40，值越大尺寸越大，可存储的信息越大
//            qrcode.setQrcodeVersion(size);
//
//            byte[] contentBytes = content.getBytes("utf-8");
//            // 图片尺寸
//            int imgSize = 67 + 12 * (size - 1);
//
//            bufImg = new BufferedImage(imgSize, imgSize,
//                    BufferedImage.TYPE_INT_RGB);
//
//            Graphics2D gs = bufImg.createGraphics();
//
//            gs.setBackground(Color.WHITE);
//            gs.clearRect(0, 0, imgSize, imgSize);
//
//            // 设定图像颜色 &gt; BLACK
//            gs.setColor(Color.BLACK);
//
//            // 设置偏移量 不设置可能导致解析出错
//            int pixoff = 2;
//            // 输出内容 &gt; 二维码
//            if (contentBytes.length > 0 && contentBytes.length < 800) {
//                boolean[][] codeOut = qrcode.calQrcode(contentBytes);
//                for (int i = 0; i < codeOut.length; i++) {
//                    for (int j = 0; j < codeOut.length; j++) {
//                        if (codeOut[j][i]) {
//                            gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3, 3);
//                        }
//                    }
//                }
//            } else {
//                System.err.println("QRCode content bytes length = "
//                        + contentBytes.length + " not in [ 0,800 ]. ");
//            }
//
//            gs.dispose();
//            bufImg.flush();
//        } catch (Exception e) {
//            log.error(e.getMessage());
//        }
//        return bufImg;
//    }


}
